import click
from Functions.MapDownloader.MapDownloader import MapDownloader
from Functions.PhotoDownload.FhotoDownloader import PhotoDownloader
from Functions.PhotoDownload.Select import Select

func_dict = {
    "MapDownloader": MapDownloader,
    "PhotoDownloader": PhotoDownloader,
    "Select": Select
}

# 用于存储临时变量
temp_vars = {}
# 当前路径，初始为根路径
current_path = []


def list_available_methods(class_obj):
    """列出类中所有非私有方法"""
    func_f = {}
    func_items = class_obj.__dict__.items()
    for func_name, func in func_items:
        if func_name[0] != "_" and callable(func):
            print(f" -- {class_obj.__name__}.{func_name}")
            func_f[func_name] = func
    return func_f


@click.group()
@click.pass_context
def cli(ctx):
    pass


@cli.command()
@click.argument('path', default='')
@click.pass_context
def ls(ctx, path):
    if path:
        parts = path.split('/')
        if parts[0] == '':
            parts = parts[1:]
        current = func_dict
        for part in parts:
            if part in current:
                current = current[part].__dict__
            else:
                print(f"路径 {path} 不存在。")
                return
        for name, obj in current.items():
            if callable(obj) and name[0] != "_":
                print(name)
    else:
        for class_name in func_dict:
            print(class_name)


@cli.command()
@click.argument('path')
@click.pass_context
def cd(ctx, path):
    global current_path
    if path == '..':
        if current_path:
            current_path.pop()
            print(f"已返回上一级，当前路径: {'/' + '/'.join(current_path)}")
        else:
            print("已经在根路径，无法再返回上一级。")
    elif path == '/':
        current_path = []
        print("已回到根路径。")
    elif path == './':
        print(f"当前路径: {'/' + '/'.join(current_path)}")
    else:
        parts = path.split('/')
        if parts[0] == '':
            current_path = []
            parts = parts[1:]
        new_path = current_path + parts
        current = func_dict
        for part in new_path:
            if part == '..':
                if current_path:
                    current_path.pop()
                    new_path = current_path + new_path[new_path.index(part)+1:]
                    current = func_dict
                    for p in current_path:
                        if p in current:
                            current = current[p].__dict__
                        else:
                            print(f"路径 {path} 不存在。")
                            return
                else:
                    print("已经在根路径，无法再返回上一级。")
                    return
            elif part in current:
                current = current[part].__dict__
            else:
                print(f"路径 {path} 不存在。")
                return
        current_path = new_path
        print(f"已进入路径: {'/' + '/'.join(current_path)}")


@cli.command()
@click.argument('command_str')
@click.pass_context
def call(ctx, command_str):
    parts = command_str.split('(', 1)
    if len(parts) != 2:
        print("Invalid call syntax. Use call func(a, b, ...)")
        return
    method_name = parts[0].strip()
    args_str = parts[1].rstrip(')').strip()
    args = []
    if args_str:
        args = [arg.strip() for arg in args_str.split(',')]

    class_obj = func_dict
    for part in current_path:
        class_obj = class_obj[part].__dict__
    class_obj = func_dict[current_path[0]] if current_path else None
    if class_obj:
        if class_obj.__name__ == 'PhotoDownloader':
            if len(args) < 3:
                print("Error: PhotoDownloader requires game_id, forum_id, and page_size as arguments.")
                return
            game_id = args[0]
            forum_id = args[1]
            page_size = args[2]
            instance = class_obj(game_id, forum_id, page_size)
            args = args[3:]
        else:
            instance = class_obj()
        method = getattr(instance, method_name, None)
        if method and callable(method):
            try:
                resolved_args = []
                for arg in args:
                    if arg.startswith('$'):
                        var = arg[1:]
                        if var in temp_vars:
                            resolved_args.append(temp_vars[var])
                        else:
                            print(f"未找到临时变量 {var}。")
                            return
                    elif arg.startswith('"') and arg.endswith('"'):
                        resolved_args.append(arg[1:-1])
                    else:
                        try:
                            if arg.isdigit():
                                resolved_args.append(int(arg))
                            elif arg.replace('.', '', 1).isdigit():
                                resolved_args.append(float(arg))
                            else:
                                resolved_args.append(arg)
                        except ValueError:
                            resolved_args.append(arg)
                if resolved_args:
                    result = method(*resolved_args)
                else:
                    result = method()
                print(f"方法 {method_name} 调用结果: {result}")
            except Exception as e:
                print(f"调用方法 {method_name} 时发生错误: {e}")
        else:
            print(f"类中未找到方法 {method_name}。")
    else:
        print("当前路径下没有可用的类。")


@cli.command()
@click.argument('class_name')
@click.pass_context
def help(ctx, class_name):
    class_obj = func_dict.get(class_name)
    if class_obj:
        print(class_obj.__doc__)
    else:
        print(f"未找到 {class_name} 对应的类。")


@cli.command()
@click.argument('var_name')
@click.pass_context
def show_var(ctx, var_name):
    if var_name in temp_vars:
        print(f"临时变量 {var_name} 的值: {temp_vars[var_name]}，类型: {type(temp_vars[var_name])}")
    else:
        print(f"未找到临时变量 {var_name}。")


@cli.command()
@click.pass_context
def show_all_methods(ctx):
    if current_path:
        class_name = current_path[-1]
        class_obj = func_dict.get(class_name)
        if class_obj:
            print(f"{class_name} 类的可用方法:")
            list_available_methods(class_obj)
        else:
            print("当前路径下没有可用的类。")
    else:
        print("所有可调用的方法:")
        for class_name, class_obj in func_dict.items():
            print(f"{class_name} 类的可用方法:")
            list_available_methods(class_obj)


@cli.command()
@click.argument('command_str')
@click.pass_context
def set(ctx, command_str):
    parts = command_str.split('=', 1)
    if len(parts) != 2:
        print("Invalid set syntax. Use set name=value or set name=func(a,b,...)")
        return
    var_name = parts[0].strip()
    value_str = parts[1].strip()

    if '(' in value_str and value_str.endswith(')'):
        if value_str.count('(') == 1 and value_str.count(')') == 1 and ',' in value_str[1:-1]:
            # 处理元组输入
            args_str = value_str[1:-1].strip()
            args = []
            if args_str:
                args = [arg.strip() for arg in args_str.split(',')]
            resolved_args = []
            for arg in args:
                if arg.startswith('$'):
                    var = arg[1:]
                    if var in temp_vars:
                        resolved_args.append(temp_vars[var])
                    else:
                        print(f"未找到临时变量 {var}。")
                        return
                elif arg.startswith('"') and arg.endswith('"'):
                    resolved_args.append(arg[1:-1])
                else:
                    try:
                        if arg.isdigit():
                            resolved_args.append(int(arg))
                        elif arg.replace('.', '', 1).isdigit():
                            resolved_args.append(float(arg))
                        else:
                            resolved_args.append(arg)
                    except ValueError:
                        resolved_args.append(arg)
            temp_vars[var_name] = tuple(resolved_args)
            print(f"临时变量 {var_name} 已设置为 {temp_vars[var_name]}，类型: {type(temp_vars[var_name])}")
        else:
            # 处理方法调用
            parts = value_str.split('(', 1)
            if len(parts) != 2:
                print("Invalid function call syntax. Use func(a, b, ...)")
                return
            method_name = parts[0].strip()
            args_str = parts[1].rstrip(')').strip()
            args = []
            if args_str:
                args = [arg.strip() for arg in args_str.split(',')]

            class_obj = func_dict
            for part in current_path:
                class_obj = class_obj[part].__dict__
            class_obj = func_dict[current_path[0]] if current_path else None
            if class_obj:
                if class_obj.__name__ == 'PhotoDownloader':
                    if len(args) < 3:
                        print("Error: PhotoDownloader requires game_id, forum_id, and page_size as arguments.")
                        return
                    game_id = args[0]
                    forum_id = args[1]
                    page_size = args[2]
                    instance = class_obj(game_id, forum_id, page_size)
                    args = args[3:]
                else:
                    instance = class_obj()
                method = getattr(instance, method_name, None)
                if method and callable(method):
                    try:
                        resolved_args = []
                        for arg in args:
                            if arg.startswith('$'):
                                var = arg[1:]
                                if var in temp_vars:
                                    resolved_args.append(temp_vars[var])
                                else:
                                    print(f"未找到临时变量 {var}。")
                                    return
                            elif arg.startswith('"') and arg.endswith('"'):
                                resolved_args.append(arg[1:-1])
                            else:
                                try:
                                    if arg.isdigit():
                                        resolved_args.append(int(arg))
                                    elif arg.replace('.', '', 1).isdigit():
                                        resolved_args.append(float(arg))
                                    else:
                                        resolved_args.append(arg)
                                except ValueError:
                                    resolved_args.append(arg)
                        if resolved_args:
                            result = method(*resolved_args)
                        else:
                            result = method()
                        temp_vars[var_name] = result
                        print(f"方法 {method_name} 调用结果已存储到临时变量 {var_name}: {result}")
                    except Exception as e:
                        print(f"调用方法 {method_name} 时发生错误: {e}")
                else:
                    print(f"类中未找到方法 {method_name}。")
            else:
                print("当前路径下没有可用的类。")
    else:
        # 处理普通赋值
        value = value_str
        if value.startswith('"') and value.endswith('"'):
            value = value[1:-1]
        try:
            if value.isdigit():
                temp_vars[var_name] = int(value)
            elif value.replace('.', '', 1).isdigit():
                temp_vars[var_name] = float(value)
            elif value.lower() == 'true':
                temp_vars[var_name] = True
            elif value.lower() == 'false':
                temp_vars[var_name] = False
            else:
                temp_vars[var_name] = value
            print(f"临时变量 {var_name} 已设置为 {temp_vars[var_name]}，类型: {type(temp_vars[var_name])}")
        except Exception as e:
            print(f"设置临时变量 {var_name} 时发生错误: {e}")


def main():
    while True:
        prompt = f"/{'/'.join(current_path)}> "
        command = input(prompt)
        if command.lower() == 'q':
            break
        try:
            cli.main(args=command.split())
        except SystemExit:
            pass


if __name__ == "__main__":
    main()

    # set forum_id=get_forum_id("崩坏：星穹铁道", "同人图")